package cn.zymall.order.service.impl;

import cn.zymall.common.utils.redis.RedisUtil;
import cn.zymall.order.dao.OrderMapper;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;

import cn.zymall.common.model.Order;
import cn.zymall.order.service.AliPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @program: mall
 * @description: 支付宝业务实现类
 * @author: YueNiao
 * @email: 1486617253@qq.com
 * @create: 2020-08-18 21:59
 **/
@Service
public class AliPayServiceImpl implements AliPayService {
	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private RedisUtil redisUtil;

	// 应用ID,您的APPID，收款账号既是您的APPID对应支付宝账号
	public static String app_id = "2016102800774359";

	// 商户私钥，您的PKCS8格式RSA2私钥
	public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChte0+X7DsIABI7u3F6XZc5lzy3vDH8Euw6AjLZVWx2qnRsKo8Kh2F7MHsS6xUSgXgvD4KdijHbdr7gGRUnvn/M462kWfXGe/nw/8V69l9qTrF2Y2JlC5JYRm29KGw3OxYG7My4P6Q2HrGJ/z9reO1CHj/8h99xV/Ko8Zy1XTXRwI8wz+5lQvwtTmLGo0QmbmnJ46xTelgswf0vDg85MnMV/t48EnOFsqB1CmYO0Q5tSiCkcJ+KpmduOufOlFy6w98NHuP/vXBzyxdVnvwZm1taZBhi/qc2JsMWrmTozRjGieJGw2CUCDjfhj8ktI7Azi2ZDiqjkoh+RvyfA3iMVuzAgMBAAECggEAOvPr7ZVNFogEEpKoNEKMWAnTUOdduEYuEexFaIEk4JXq2vsg1JY19SD/AXoE9SWXRvrZU08IRswRzSZdbUwXr6XIHV6dEJnwD/owAHne7CTJvF83bjSLO00e5sgAOk4QC37tsVq882k4OQ1S+dhu7wyLsCNAv8U4ytMyAaM32VL/73Cxf0mzQYBCrWSnWbH63/rW3prF/fBT+FM71C2uQYsp3pAUdxQOLH3XvQM/ZByqp/A1MtU53QNuOeJWnME6auuUcARJ2s1NQUZ6tfT9wfc8Jca5jYqKAW8fXQsozhdw+wicHLhLGfNVI0Yc9pvyJqqhO7yMPITyYrCApsCZwQKBgQDqi7TavlhL1vWAY7Cw4IG3KudZqSQP0dJUakWsa4jsujjUOpGA8AJTTrWEmt0TPbYDjvI2UQsuLvBaqGzMFsH8Iwb20rKqfvZpVK/uDK8k2F/LElo0ciOhMmHXxcYxxwebc8US1uFdfdPraeSO9tP6hMNvYKIV9Lu7ZDFFGqSeeQKBgQCwgKk8ZMQdzNI8liB6A61TgwEWXzGO46EI0whlQCJy1I9ooPgahiBo9ubhu+OxyLxs3QxmCqM/hUVWqTiUKACKEVLmHuGjsKlxvpeYr3ku4KyzNjgq100h1vW+qFWN48YYgezEpwOH11hTecmPzkSqIQh27iQtvIGqBV4p8zXQiwKBgCSXBu/ZIg0yy7nr03TEkXfxyYXDTUzqftWMfrIXVJUZuCPjvy9OQg6dCNRXFIYb6nlDo6W1nvjlebmq7M4p/rlG/Z8j35uZkvd7rraEZA5rcwZLJqdn5wcOxRTUVccONbGarfPycdYT+yuOqYlkGE3MyHBnsuGZ/G+PgeA199iBAoGBAKz5emGQk05tI4By1GMfZWbZlWA6bJQPawr93lV0FA6bV+v/DQbZebvEdKK3Az+BbX/25ia+uBwRXNHAR42S4mxs6+RQUWudP4IUefcNyOJzF20Obt81XwcR5oYx7J6Aoev0sHhNAT3IgmxUh3+ic1KTyvrbCaO1ARIB7rWH/65fAoGATJ0Ic9SOPVJPSaUPPUjIv2TT/2VVOej78IEQUF42ALtvVyXCnvFVYCmaQQFfeAPm/dI0DnMnji2qESFOW2Zui2cmX7HCpaMQWAPxtXBzHmMHaakJe3R0ODb4haoHThEtxNx9JUULa94wmO50V1nRMYgWZXtahW9+Z32wpZpDVVQ=";

	// 支付宝公钥,查看地址：https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
	public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1WxDQzo79dMmAFuFuMh4s1RngVciUiZuoqcD0bHBFfAxS+8BwA++90RiWNPiC9pBLRLIlNh1/6vKE8MueaRD6C/4sNq4gIb1nnoTGaWbPIIBiZL4b/GT7hPc5suKGWTvRJVU3gV04kaTdqPQONbMZ2P3APkFp8/UJnhqSDLUk0Gz6y5ztB0Q82ppXMkwMq5OW7mIEtrA05MIPZlVeQbBW/ypvQ+B1kK4M38oKn3kfZ8hMYwu+9iPNhzVBSVXwxWG/F7YxB5Cmr2m/bIHBLaNtn60+LR5IvWa/ESKRmQpwAM62P4xDy2sMDdCwWA1Z8GPT7wu9GIcdbG2MvfbSu5XwIDAQAB";

	// 服务器异步通知页面路径  需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
//	public static String notify_url = "http://yueniao.vipgz4.idcfengye.com/return_urlChong";
	public static String notify_url = "http://yueniao.vipgz4.idcfengye.com:7001/notify";
	// 页面跳转同步通知页面路径 需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
//	public static String return_url = "http://yueniao.vipgz4.idcfengye.com/return_urlChong";
	public static String return_url = "http://www.baidu.com/";

	// 签名方式
	public static String sign_type = "RSA2";

	// 字符编码格式
	public static String charset = "utf-8";

	// 支付宝网关
	public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

	// 支付宝网关
	public static String log_path = "C:\\";

	/**
	 * 调用阿里支付接口
	 * @param request
	 * @param response
	 * @param order
	 */
	@Override
	@ResponseBody
	public void toPay(HttpServletRequest request, HttpServletResponse response, Order order) throws IOException {
		order.setPayMode("支付宝");
		orderMapper.updateById(order);
		/**
		 * 校验redis中订单是否存在
		 */
		Order o = (Order)JSON.parse(redisUtil.get("order"+order.getOrderId())+"");
		if(o==null){
			//不存在修改订单状态为失效订单
			order.setOrderStatus((byte)9);
			orderMapper.updateById(order);
			return;
		}

		//获得初始化的AlipayClient
		AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,app_id,merchant_private_key, "json",charset,alipay_public_key,sign_type);
		//设置请求参数
		AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
		alipayRequest.setReturnUrl(return_url);
		alipayRequest.setNotifyUrl(notify_url);

		//商户订单号，商户网站订单系统中唯一订单号，必填
		String outTradeNo = order.getOrderId();
		System.out.println("out_trade_no="+outTradeNo);
		//付款金额，必填
		BigDecimal totalAmount = order.getOrderMoney();
		//订单名称，必填
		String subject = "商品购买";
		//商品描述，可空
		String body = order.getSpuNorms();

		alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
				+ "\"total_amount\":\""+ totalAmount +"\","
				+ "\"subject\":\""+ subject +"\","
				+ "\"body\":\""+ body +"\","
				+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
		//请求
		String result = "";
		try {
			result = alipayClient.pageExecute(alipayRequest).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}

		//输出
		response.setContentType("text/html;charset=" + charset);
		// 直接将完整的表单html输出到页面
		response.getWriter().write(result);
		response.getWriter().flush();
		response.getWriter().close();
	}

	/**
	 * 支付成功回调，修改订单状态
	 * @param request
	 * @return
	 */
	@Override
	public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {



		Map<String, String> map = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			map.put(name, valueStr);
		}
		System.out.println("支付结果---：" + map.toString());
		//调用SDK验证签名
		boolean signVerified = false;
		try {
			signVerified = AlipaySignature.rsaCheckV1(map, alipay_public_key, charset, sign_type);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (signVerified) {
			System.out.println("支付结果---：" + map.toString());
			/**
			 * 支付结果---：{
			 * gmt_create=2020-08-01 10:02:23, 订单创建时间
			 * charset=utf-8, 字符集
			 * gmt_payment=2020-08-01 10:02:31, 订单支付时间
			 * notify_time=2020-08-01 10:02:32, 订单异步回调时间
			 * subject=充值, 订单标题；
			 * buyer_id=2088102181282414, //买方id
			 * body=余额充值,  订单描述;
			 * invoice_amount=156.00,   交易金额
			 * version=1.0,  版本
			 * notify_id=2020080100222100232082410506219689, 异步id
			 * fund_bill_list=[  交易支付使用的资金渠道
			 * {"amount":"156.00",      金额
			 * "fundChannel":"ALIPAYACCOUNT"}], 支付宝账户
			 * notify_type=trade_status_sync,
			 * out_trade_no=73380d5c-ee95-4d70-8e9d-69cd9b1fece0, 商家生成订单号
			 * total_amount=156.00,  订单金额
			 * trade_status=TRADE_SUCCESS,  支付结果状态
			 * trade_no=2020080122001482410501155629, 支付宝订单号
			 * auth_app_id=2016102800774359,
			 * receipt_amount=156.00,
			 * point_amount=0.00,
			 * app_id=2016102800774359,
			 * buyer_pay_amount=156.00,
			 * seller_id=2088102181352269}
			 *
			 */
			String tradNo = map.get("out_trade_no");
			//根据交易流水号查询交易信息
			//交易成功
			if ("TRADE_SUCCESS".equals(map.get("trade_status"))) {

				/**
				 * 删除redis中订单
				 */

				Order redisOrder = (Order)JSON.parse(redisUtil.get("order"+tradNo)+"");
				if(redisOrder!=null){
					redisUtil.del("order"+tradNo);
				}

				Order o=new Order();
				o.setOrderId(map.get("out_trade_no"));
				o.setOrderStatus((byte)2);
				o.setPayTime(new Date());

				orderMapper.updateById(o);
			}
			try {
				PrintWriter out = response.getWriter();
				out.print("success");
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
		} else {
			// TODO 验签失败则记录异常日志，并在response中返回failure.
			try {
				PrintWriter out = response.getWriter();
				out.print("failure");
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 订单查询
	 * @param id 	商户订单号
	 * @return
	 * @throws AlipayApiException
	 */
	@Override
	public boolean search(String id) throws AlipayApiException {
		//查询订单是否支付完成

		Order order = orderMapper.selectById(id);
		if(order.getOrderStatus()!=1&&order.getOrderStatus()>0){
			return true;
		}

		//获得初始化的AlipayClient
		AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,app_id,merchant_private_key, "json",charset,alipay_public_key,sign_type);
		WebUtils.setNeedCheckServerTrusted(false);
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		request.setBizContent("{" +
				"\"out_trade_no\":\"25141ebb-fb6f-4781-811f-91cceed11356\"," +
//				"\"trade_no\":\"2020071122001482410501142496\"," +
//				"\"org_pid\":\"2088101117952222\"," +
				"      \"query_options\":[" +
				"        \"TRADE_SETTLE_INFO\"," +
				"        \"trade_status\"" +

				"      ]" +
				"  }");
		AlipayTradeQueryResponse response = alipayClient.execute(request);
		if(response.isSuccess()){
			System.out.println("状态----"+response.getTradeStatus());
			if ("TRADE_STATUS_SUCCESS".equals(response.getTradeStatus()) ||"TRADE_STATUS_FINISHED".equals(response.getTradeStatus()) ||"TRADE_SUCCESS".equals(response.getTradeStatus())) {
				// 更新订单状态
				Order o=new Order();
				o.setOrderId(id);
				o.setOrderStatus((byte)2);
				o.setPayTime(new Date());
				orderMapper.updateById(o);
				return true;
			}
			System.out.println("调用成功");
		} else {
			System.out.println("调用失败");
		}
		return false;
	}
}
